﻿using CrawlerFramework.Models;
using CrawlerFramework.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CrawlerFramework.ConfigEntity
{
    /// <summary>
    /// Helper methods for working with Config classes
    /// </summary>
    public static class ConfigHelper
    {
        /// <summary>
        /// Get all links in db that satisfy the defined pattern
        /// </summary>
        /// <param name="linkConfig">LinkConfig instance that defined the pattern</param>
        /// <returns></returns>
        public static IEnumerable<Models.Link> GetLinks(this LinkConfig linkConfig)
        {
            var links = new List<Link>();
            using (var linkRepo = new LinkRepository())
            {
                if (linkConfig.Matches.Count > 0)
                {
                    var allLinks = linkRepo.All.ToList();
                    var where = new Func<Link, bool>(link =>
                    {
                        var hasRanToday = link.EndDate.HasValue && link.CrawlStatus == CrawlStatus.Completed && link.EndDate.Value.Date == DateTime.Now.Date;
                        if (!hasRanToday)
                            return linkConfig.IsSatisfy(link.Url);

                        return false;
                    });

                    links.AddRange(allLinks.Where(where));
                }

                foreach (var url in linkConfig.Urls)
                {
                    var link = linkRepo.Single(l => l.Url == url.Context);

                    if (link == null)
                    {
                        link = new Link { Url = url.Context, CrawlStatus = CrawlStatus.Initial };
                        linkRepo.Add(link);
                        linkRepo.Save();
                        links.Add(link);
                    }
                    else
                    {
                        if (!links.Contains(link))
                            links.Add(link);
                    }
                }

                return links;
            }
        }

        public static string GetReflectorTypeString(this LinkConfig link)
        {
            var builder = new StringBuilder();
            builder.Append(link.FullClassName);
            if (!string.IsNullOrEmpty(link.AssemblyName))
                builder.AppendFormat(", {0}", link.AssemblyName);

            return builder.ToString();
        }
    }
}
